package wxBiz

import (
	"encoding/json"
	"t11Lib/t11Errors"
	"t11Lib/t11Log"
	"t11Lib/t11Model"
	"亚太-iot-服务器/biz"
	"亚太-iot-服务器/biz/wsBroker"
	"亚太-iot-服务器/models"
)

// 处理websocket数据包
func HandleWsPkt(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data string) t11Errors.T11Error {
	var pkg biz.MqttMsg
	if e := json.Unmarshal([]byte(data), &pkg); e != nil {
		return t11Errors.Wrap(e)
	}
	t11Log.Debuglnf("收到websocket数据包:%+v", pkg)
	switch pkg.Cmd {
	case biz.CmdToGateway:
		return handlePktToGateway(dbConn, wsConn, &pkg)
	case biz.CmdToDev:
		return handlePktToDev(dbConn, wsConn, &pkg)
	default:
		return t11Errors.New("非法的数据包")
	}
}

type _toGwCmdHandler struct{}

var toGwCmdHandler _toGwCmdHandler

func (self _toGwCmdHandler) hasGateway(conn *t11Model.DbConn, wsConn *wsBroker.WsConn, gwId string) t11Errors.T11Error {
	gw, err := models.GatewayDao.GetById(conn, gwId)
	if err != nil {
		return err
	}
	if gw.UserId != wsConn.GetClient().ToId() {
		return t11Errors.New("没有网关权限")
	} else {
		return nil
	}
}

func (self _toGwCmdHandler) hasDev(conn *t11Model.DbConn, wsConn *wsBroker.WsConn, devId string) t11Errors.T11Error {
	_, ret := models.UserDeviceDao.Get(conn, devId, wsConn.GetClient())
	return ret
}

func (self _toGwCmdHandler) redirectToGateway(conn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg, checkDev ...bool) t11Errors.T11Error {
	_checkDev := true
	if len(checkDev) > 0 {
		_checkDev = checkDev[0]
	}
	if _checkDev {
		if err := self.hasDev(conn, wsConn, data.DevId); err != nil {
			return err
		}
	} else {
		if err := self.hasGateway(conn, wsConn, data.GatewayId); err != nil {
			return err
		}
	}
	//直接将当前数据发送给mqtt服务器
	return biz.MqttMsgSender.SendMsg(data)
}

//notify网关添加设备
func (self _toGwCmdHandler) handleAddDev(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg) t11Errors.T11Error {
	return self.redirectToGateway(dbConn, wsConn, data, false)
}

//notify取消添加网关
func (self _toGwCmdHandler) handleCancelAddDev(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg) t11Errors.T11Error {
	return self.redirectToGateway(dbConn, wsConn, data, false)
}

//处理查询网关状态
func (self _toGwCmdHandler) handleQueryGatewayStatus(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg) t11Errors.T11Error {
	return self.redirectToGateway(dbConn, wsConn, data, false)
}

// 删除门锁设备
func (self _toGwCmdHandler) handleDelDev(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg) t11Errors.T11Error {
	if err := self.hasDev(dbConn, wsConn, data.DevId); err != nil {
		return err
	}
	if self.hasGateway(dbConn, wsConn, data.GatewayId) != nil {
		// 分享用户删除设备
		return biz.UserBiz.DeleteDevice(dbConn, data.DevId, wsConn.GetClient())
	} else {
		// 管理员用户删除设备
		return biz.MqttMsgSender.SendMsg(data)
	}
}

// 门锁心跳
func (self _toGwCmdHandler) handleHeartDev(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg) t11Errors.T11Error {

	if err := self.hasDev(dbConn, wsConn, data.DevId); err != nil {
		return err
	}
	if err := self.hasGateway(dbConn, wsConn, data.GatewayId); err != nil {
		return err
	}

	return biz.MqttMsgSender.SendMsg(data)
}

// 处理发给网关的websocket数据包
func handlePktToGateway(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg) t11Errors.T11Error {
	switch data.SubCmd {
	case biz.SubCmdToGw_AddDev:
		return toGwCmdHandler.handleAddDev(dbConn, wsConn, data)
	case biz.SubCmdToGw_CancelAddDev:
		return toGwCmdHandler.handleCancelAddDev(dbConn, wsConn, data)
	case biz.SubCmdToGw_QueryGatewayStatus:
		return toGwCmdHandler.handleQueryGatewayStatus(dbConn, wsConn, data)
	case biz.SubCmdToGw_DelDev:
		return toGwCmdHandler.handleDelDev(dbConn, wsConn, data)
	case biz.SubCmdFromGw_HeartDev:
		return toGwCmdHandler.handleHeartDev(dbConn, wsConn, data)
	default:
		return t11Errors.New("非法的数据包")
	}
}

// 处理发送给门锁设备的数据包
func (self _toGwCmdHandler) handleToDev(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg) t11Errors.T11Error {
	return self.redirectToGateway(dbConn, wsConn, data, true)
}

// 处理发给门锁设备的websocket数据包
func handlePktToDev(dbConn *t11Model.DbConn, wsConn *wsBroker.WsConn, data *biz.MqttMsg) t11Errors.T11Error {
	switch data.SubCmd {
	case biz.SubCmdToDev_CmdToDev:
		return toGwCmdHandler.handleToDev(dbConn, wsConn, data)
	default:
		return t11Errors.New("非法的数据包")
	}
}